home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
SNNSV32.ZIP
/
SNNSv3.2
/
kernel
/
sources
/
trans_f.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-25
|
36KB
|
1,584 lines
/*****************************************************************************
FILE : trans_f.c
SHORTNAME :
SNNS VERSION : 3.2
PURPOSE : SNNS-Kernel transfer functions
NOTES :
AUTHOR : Niels Mache
DATE : 25.06.90
CHANGED BY : Sven Doering, Ralf Huebner, Marc Seemann (Uni Tuebingen)
IDENTIFICATION : @(#)trans_f.c 1.29 3/15/94
SCCS VERSION : 1.29
LAST CHANGE : 3/15/94
Copyright (c) 1990-1994 SNNS Group, IPVR, Univ. Stuttgart, FRG
******************************************************************************/
#include <stdio.h>
#include <math.h>
#include <values.h>
#include <string.h>
#include "kr_typ.h" /* Kernel types and constants */
#include "kr_const.h" /* Constant Declarators for SNNS-Kernel */
#include "func_mac.h" /* Transfer function macros */
#include "glob_typ.h"
#include "kr_mac.h"
#include "cc_mac.h"
#include "trans_f.ph"
#ifdef __BORLANDC__
#pragma option -w-
#endif
/*#################################################
GROUP: Aritmetic Functions
#################################################*/
/* exp function that prevents from over- and underflow, that means
exp_s ist a "save" exp function.
*/
static float exp_s( float arg )
{
if (arg > 88.72) return( MAXFLOAT );
else if (arg < -102.0) return( MINFLOAT );
return( exp( arg ) );
}
/*#################################################
GROUP: Unit Output Functions
#################################################*/
/* Linear Output Function
This function isn't used now, because the identity output function is
the NULL pointer.
*/
FlintType OUTP_Identity(register FlintType activation)
{
return( activation );
}
/* Clipping [0,1] function
*/
FlintType OUT_Clip_01(register FlintType activation)
{
if (activation < 0.0) return( (FlintType) 0.0 );
if (activation > 1.0) return( (FlintType) 1.0 );
return( activation );
}
/* Clipping [-1,1] function
*/
FlintType OUT_Clip_11(register FlintType activation)
{
if (activation < -1.0) return( (FlintType) -1.0 );
if (activation > 1.0) return( (FlintType) 1.0 );
return( activation );
}
/* Threshold 0.5 Output Function
*/
FlintType OUT_Threshold05(register FlintType activation)
{
if (activation < 0.5) return( (FlintType) 0.0 );
return( (FlintType) 1.0 );
}
/*#################################################
GROUP: Unit Activation Functions
#################################################*/
/* Linear Activation Function
*/
FlintType ACT_Linear(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( sum );
}
/* Brain-State-in-a-Box Function
*/
FlintType ACT_BSBFunction(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( sum * GET_UNIT_BIAS( unit_ptr ));
}
/* Minimum Function (Unit's output and weight)
*/
FlintType ACT_MinOutPlusWeight(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType min1, min2;
min1 = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr )) {
min1 = GET_OUTPUT + GET_WEIGHT;
while (GET_NEXT_LINK)
if ((min2 = GET_OUTPUT + GET_WEIGHT) < min1)
min1 = min2;
}
else
if (GET_FIRST_SITE( unit_ptr )) {
min1 = GET_SITE_VALUE;
while (GET_NEXT_SITE)
if ((min2 = GET_SITE_VALUE) < min1)
min1 = min2;
}
return( min1 );
}
/* Hyperbolic Tangent Function
*/
FlintType ACT_TanHFunction(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( tanh( sum + GET_UNIT_BIAS( unit_ptr )));
}
/* Hyperbolic Tangent Function plus the bias
*/
FlintType ACT_TanHFunctionPlusBias(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( tanh( sum) + GET_UNIT_BIAS( unit_ptr ));
}
/* Hyperbolic Tangent Function of (unit_ptr/2)
*/
FlintType ACT_TanHFunction_Xdiv2( unit_ptr )
UNIT_PTR unit_ptr;
{
ACT_FUNC_DEFS
register FlintType sum;
float expon;
float wert;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
wert = sum + GET_UNIT_BIAS( unit_ptr );
if( wert > 9 ) wert = 9;
if( wert < -9 ) wert = -9;
expon = exp_s(wert);
return( (expon - 1) / (expon + 1));
}
/* Sigmoid Function
*/
FlintType ACT_Logistic(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( (FlintType) (1.0 / (1.0 + exp_s( -sum - GET_UNIT_BIAS( unit_ptr )))) );
}
/* Elliott Function
*/
FlintType ACT_Elliott(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
sum += GET_UNIT_BIAS(unit_ptr);
if (sum <= 0.0)
return (FlintType) sum/(1.0 - sum);
else
return (FlintType) sum/(1.0 + sum);
}
/* Perceptron Function
*/
FlintType ACT_Perceptron(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum >= GET_UNIT_BIAS(unit_ptr))
return( (FlintType) 1.0 );
return( (FlintType) 0.0 );
}
/* Signum Function
*/
FlintType ACT_Signum(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum > 0.0)
return( (FlintType) 1.0 );
return( (FlintType) -1.0 );
}
/* Signum0 Function
*/
FlintType ACT_Signum0(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum > 0.0) return( (FlintType) 1.0 );
if (sum < 0.0) return( (FlintType) -1.0 );
return( (FlintType) 0.0 );
}
/* Step Function
*/
FlintType ACT_StepFunction(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum > 0.0) return( (FlintType) 1.0 );
return( (FlintType) 0.0 );
}
/* Hysteresis Step Function
*/
FlintType ACT_HystStepFunction(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
FlintType Schwellwert = 0.1;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum - (unit_ptr->bias) > Schwellwert) return( (FlintType) 1.0 );
if (sum - (unit_ptr->bias) < -Schwellwert) return( (FlintType) 0.0 );
return( unit_ptr->act );
}
/* Bi-Directional Associative Memory
*/
FlintType ACT_BAMFunction(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum > 0.0) return( (FlintType) 1.0 );
if (sum < 0.0) return( (FlintType) -1.0 );
return( unit_ptr->Out.output );
}
/* Rummelhart-McClelland's activation function for the delta rule
*/
FlintType ACT_RM (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType RM_act, sum;
FlintType Eparam=.15, Dparam=.15;
sum = 0.0;
if (GET_FIRST_UNIT_LINK (unit_ptr))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE (unit_ptr))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
if (sum > 0)
RM_act = (unit_ptr->act + (Eparam * sum * (1 - unit_ptr->act))
- (Dparam * unit_ptr->act));
else
RM_act = (unit_ptr->act + (Eparam * sum * (unit_ptr->act + 1))
- (Dparam * unit_ptr->act));
return (RM_act);
}
/* demonstation function: this function act like the Logistic function,
but the site with the name "Inhibit" will be skipped.
*/
FlintType ACT_LogisticI(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_SITE( unit_ptr ))
/* Do not calculate the 'Inhibit' site */
do
if (strcmp( "Inhibit", GET_SITE_NAME ))
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
else
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
return( (FlintType) (1.0 / (1.0 + exp_s( -sum - GET_UNIT_BIAS( unit_ptr )))) );
}
/* help function for all Radial Basis Activation, Derivation and Learn
* functions. Computes the square of the L2-Norm of (T - X), where T is the
* vector of all weights from links leading to <unit_ptr> and X is the
* vector of output units the links are connected from.
* Store calculated value into value_a field of the current unit.
* ALL FUTURE RBF ACTIVATION FUNCTIONS HAVE TO CALL THIS FUNCTION !!!!!!!!!!
*/
FlintType RbfUnitGetNormsqr(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType norm_2 = 0.0; /* |X - T|^2 */
register FlintType diff; /* difference */
if (!GET_FIRST_UNIT_LINK(unit_ptr))
{
fprintf(stderr,"No input links!\n");
return norm_2;
}
do
{
diff = GET_OUTPUT - GET_WEIGHT;
norm_2 += diff * diff;
}
while (GET_NEXT_LINK);
return unit_ptr -> value_a = norm_2;
}
/*
* Gaussian RBF Activation function: h(L2, s) = exp(-s*L2^2)
* where L2 is the L2 Norm (see RbfUnitGetNormsqr), and s is the bias
* of <unit_ptr>.
*/
FlintType ACT_RBF_Gaussian(struct Unit *unit_ptr)
{
register FlintType norm_2;
norm_2 = RbfUnitGetNormsqr(unit_ptr);
return (FlintType) exp_s(- GET_UNIT_BIAS(unit_ptr)*norm_2);
}
/*
* Multiquadratic Activation function: h(L2, s) = sqrt(s^2 + L2^2)
*/
FlintType ACT_RBF_Multiquadratic(struct Unit *unit_ptr)
{
register FlintType norm_2;
norm_2 = RbfUnitGetNormsqr(unit_ptr);
return (FlintType) sqrt(norm_2 + GET_UNIT_BIAS(unit_ptr));
}
/*
* Thin plate splines Activation function: h(L2, s) = (L2*s)^2*ln(L2*s)
*/
FlintType ACT_RBF_Thinplatespline(struct Unit *unit_ptr)
{
register FlintType norm_2;
register FlintType bias;
norm_2 = RbfUnitGetNormsqr(unit_ptr);
bias = GET_UNIT_BIAS(unit_ptr);
if (norm_2 == (FlintType) 0.0)
return (FlintType) 0.0;
else
return (FlintType) bias*bias*norm_2*(0.5*log(norm_2) + log(bias));
}
/* Linear Activation Function + BIAS
*/
FlintType ACT_Linear_bias(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( sum + GET_UNIT_BIAS(unit_ptr));
}
/* NOTE: This function is nothing but a threshold function,
which checks, whether the netinput is greater or equal 2, and if so
returns 1.0, else 0.0 .
*/
FlintType ACT_at_least_2 (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum = 0.0;
if (GET_FIRST_UNIT_LINK (unit_ptr)) {
do {
sum += GET_WEIGHTED_OUTPUT;
} while (GET_NEXT_LINK);
} else {
if (GET_FIRST_SITE (unit_ptr)) {
do {
sum += GET_SITE_VALUE;
} while (GET_NEXT_SITE);
} /*if*/
} /*if*/
if (sum >= 2.0) {
return ( (FlintType) 1.0);
} else {
return ( (FlintType) 0.0);
} /*if*/
} /* ACT_at_least_2 */
FlintType ACT_less_than_0 (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum = 0.0;
if (GET_FIRST_UNIT_LINK (unit_ptr)) {
do {
sum += GET_WEIGHTED_OUTPUT;
} while (GET_NEXT_LINK);
} else {
if (GET_FIRST_SITE (unit_ptr)) {
do {
sum += GET_SITE_VALUE;
} while (GET_NEXT_SITE);
} /*if*/
} /*if*/
if (sum >= 0.0) {
return ( (FlintType) 0.0);
} else {
return ( (FlintType) 1.0);
} /*if*/
} /* ACT_less_than_0 */
FlintType ACT_at_least_1 (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum = 0.0;
if (GET_FIRST_SITE (unit_ptr)) {
do {
sum += GET_SITE_VALUE;
} while (GET_NEXT_SITE);
} else {
if (GET_FIRST_UNIT_LINK (unit_ptr)) {
do {
sum += GET_WEIGHTED_OUTPUT;
} while (GET_NEXT_LINK);
} /*if*/
} /*if*/
if (sum >= 1.0) {
return ( (FlintType) 1.0);
} else {
return ( (FlintType) 0.0);
} /*if*/
} /* ACT_at_least_1 */
FlintType ACT_at_most_0 (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum = 0.0;
if (GET_FIRST_UNIT_LINK (unit_ptr)) {
do {
sum += GET_WEIGHTED_OUTPUT;
} while (GET_NEXT_LINK);
} else {
if (GET_FIRST_SITE (unit_ptr)) {
do {
sum += GET_SITE_VALUE;
} while (GET_NEXT_SITE);
} /*if*/
} /*if*/
if (sum > 0.0) {
return ( (FlintType) 0.0);
} else {
return ( (FlintType) 1.0);
} /*if*/
} /* ACT_at_most_0 */
FlintType ACT_Product (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType prod = 1.0;
if (GET_FIRST_UNIT_LINK (unit_ptr)) {
do {
prod *= GET_WEIGHTED_OUTPUT;
if (prod == 0.0) {
break;
} /*if*/
} while (GET_NEXT_LINK);
} else {
if (GET_FIRST_SITE (unit_ptr)) {
do {
prod *= GET_SITE_VALUE;
if (prod == 0.0) {
break;
} /*if*/
} while (GET_NEXT_SITE);
} /*if*/
} /*if*/
return (prod);
} /* ACT_Product () */
FlintType ACT_exactly_1 (struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum = 0.0;
if (GET_FIRST_UNIT_LINK (unit_ptr)) {
do {
sum += GET_WEIGHTED_OUTPUT;
} while (GET_NEXT_LINK);
} else {
if (GET_FIRST_SITE (unit_ptr)) {
do {
sum += GET_SITE_VALUE;
} while (GET_NEXT_SITE);
} /*if*/
} /*if*/
if ((sum > 0.8) && (sum < 1.2)) {
return (1.0);
} else {
return (0.0);
} /*if*/
} /* ACT_exactly_1 */
/*****************************************************************************
FUNCTION : ACT_TD_Logistic
PURPOSE : logistic activation function for use in time delay networks
RETURNS : activation
NOTES : the TD section of the unit must be initialized correct
the units must be sorted TOPOLOGIC_LOGICAL
UPDATE : 19.2.93 M. Vogt
******************************************************************************/
FlintType ACT_TD_Logistic(struct Unit *unit_ptr)
{
/* the common macros are not used */
register FlintType sum;
register UNIT_PTR ref_unit;
register int source_offset;
register struct Link *link;
if (unit_ptr -> TD.td_connect_typ == 0)
return ACT_Logistic(unit_ptr);
ref_unit = *(unit_ptr -> TD.my_topo_ptr + unit_ptr -> TD.target_offset);
source_offset = unit_ptr -> TD.source_offset;
sum = 0.0;
if ((ref_unit -> flags) & UFLAG_DLINKS)
{
link = (struct Link *) ref_unit->sites;
while (link != (struct Link *) NULL)
{
sum += (*(link->to->TD.my_topo_ptr + source_offset))->Out.output
* link->weight;
link = link->next;
}
}
else
{
fprintf(stderr,
"Warning: Illegal link structure used in time delay layer\n");
}
return( (FlintType) (1.0 / (1.0 + exp_s( -sum - ref_unit->bias))) );
}
/*****************************************************************************
FUNCTION : ACT_TD_Elliott
PURPOSE : elliott activation function for use in time delay networks
RETURNS : activation
NOTES : the TD section of the unit must be initialized correct
the units must be sorted TOPOLOGIC_LOGICAL
UPDATE : 5.3.93 M. Vogt
******************************************************************************/
FlintType ACT_TD_Elliott(struct Unit *unit_ptr)
{
/* the common macros are not used */
register FlintType sum;
register UNIT_PTR ref_unit;
register int source_offset;
register struct Link *link;
if (unit_ptr -> TD.td_connect_typ == 0)
return ACT_Elliott(unit_ptr);
ref_unit = *(unit_ptr -> TD.my_topo_ptr + unit_ptr -> TD.target_offset);
source_offset = unit_ptr -> TD.source_offset;
sum = 0.0;
if ((ref_unit -> flags) & UFLAG_DLINKS)
{
link = (struct Link *) ref_unit->sites;
while (link != (struct Link *) NULL)
{
sum += (*(link->to->TD.my_topo_ptr + source_offset))->Out.output
* link->weight;
link = link->next;
}
}
else
{
fprintf(stderr,
"Warning: Illegal link structure used in time delay layer\n");
}
sum += ref_unit->bias;
if (sum <= 0.0)
return (FlintType) sum/(1.0 - sum);
else
return (FlintType) sum/(1.0 + sum);
}
/* This function is called by a xgui function for kohonen networks */
void kohonen_SetExtraParameter(int x)
/* no. of layer chosen in remote panel */
{
ExtraParameter=x;
}
/* Activate specific layer of the net chosen in the remote panel, to set
the layer call: kohonen_SetExtraParameter( Layer )
*/
FlintType ACT_Component( UNIT_PTR unit_ptr )
{
ACT_FUNC_DEFS
register FlintType sum;
int i=1,n;
n = ExtraParameter;
sum = 0.0;
if (GET_FIRST_SITE( unit_ptr ))
sum = GET_SITE_VALUE;
else
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum=GET_WEIGHT;
while((i++<n)&&GET_NEXT_LINK);
return( sum );
}
/* Calculate the simple euclidic distance
between in-vector and weight-vector for kohonen networks
*/
FlintType ACT_Euclid( UNIT_PTR unit_ptr )
{
ACT_FUNC_DEFS
register FlintType dist;
dist= 0.0;
if (GET_FIRST_SITE( unit_ptr ))
do
dist += GET_SITE_VALUE;
while (GET_NEXT_SITE);
else
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
dist += GET_EUCLID_COMP;
while (GET_NEXT_LINK);
return(sqrt(dist));
}
/*#################################################
GROUP: Derivation Functions of the Activation Functions
#################################################*/
/* Sigmoid Derivation Function
*/
FlintType ACT_DERIV_Logistic(struct Unit *unit_ptr)
{
return( GET_UNIT_ACT( unit_ptr ) * (1.0 - GET_UNIT_ACT( unit_ptr )) );
}
/* Elliott Derivation Function
*/
FlintType ACT_DERIV_Elliott(struct Unit *unit_ptr)
{
register FlintType act;
if ((act = GET_UNIT_ACT(unit_ptr)) <= 0.0)
act = 1.0 + act;
else
act = 1.0 - act;
return (act*act);
}
/* Sigmoid Derivation Function for TD Networks
*/
FlintType ACT_DERIV_TD_Logistic(struct Unit *unit_ptr)
{
return( GET_UNIT_ACT( unit_ptr ) * (1.0 - GET_UNIT_ACT( unit_ptr )) );
}
/* Elliott Derivation Function for TD Networks
*/
FlintType ACT_DERIV_TD_Elliott(struct Unit *unit_ptr)
{
register FlintType act;
if ((act = GET_UNIT_ACT(unit_ptr)) <= 0.0)
act = 1.0 + act;
else
act = 1.0 - act;
return (act*act);
}
/* Identity Derivation Function
*/
FlintType ACT_DERIV_Identity(struct Unit *unit_ptr)
{
return( (FlintType) 1.0 );
}
/* Brain-State-in-a-Box Derivation Function
*/
FlintType ACT_DERIV_BSBFunction(struct Unit *unit_ptr)
{
return( GET_UNIT_BIAS( unit_ptr ));
}
/* TanH Derivation Function
*/
FlintType ACT_DERIV_TanHFunction(struct Unit *unit_ptr)
{
return(1.0-GET_UNIT_ACT( unit_ptr ) * (GET_UNIT_ACT( unit_ptr )) );
}
/* TanH Derivation Function
*/
FlintType ACT_DERIV_TanHFunction_Xdiv2(struct Unit *unit_ptr)
{
return(1.0-(GET_UNIT_ACT( unit_ptr ) * (GET_UNIT_ACT( unit_ptr )))/2 );
}
/* Dummy function for the derivation functions. Returns always the value 1.0.
This function is used for activation functions that can't have a derivation
function.
NOTE: All activation functions have to provide a derivation function.
*/
FlintType ACT_DERIV_Dummy(struct Unit *unit_ptr)
{
return( (FlintType) 1.0 );
}
/* Gaussian Radial Basis Derivation functionS
* depending on Aux: 0 derivated to T
* 1 derivated to s (BIAS)
* 2 derivated to T if value_a holds norm ^ 2;
* 3 derivated to s if value_a holds norm ^ 2;
* others: const 1;
*/
FlintType ACT_DERIV_RBF_Gaussian(struct Unit *unit_ptr)
{
register FlintType rc; /* return value */
register FlintType norm_2; /* norm ^ 2 */
switch (unit_ptr -> Aux.int_no)
{
case 0:
/* derivated to norm_2: */
norm_2 = RbfUnitGetNormsqr(unit_ptr);
rc = (FlintType) -GET_UNIT_BIAS(unit_ptr)
* exp_s(- GET_UNIT_BIAS(unit_ptr)*norm_2);
break;
case 1:
/* derivated to BIAS: */
norm_2 = RbfUnitGetNormsqr(unit_ptr);
rc = (FlintType) -norm_2
* exp_s(- GET_UNIT_BIAS(unit_ptr)*norm_2);
break;
case 2:
/* derivated to norm_2: (norm ^ 2 = value_a) */
rc = (FlintType) -GET_UNIT_BIAS(unit_ptr)
* exp_s(- GET_UNIT_BIAS(unit_ptr)*unit_ptr -> value_a);
break;
case 3:
/* derivated to BIAS: (norm ^ 2 = value_a) */
rc = (FlintType) -unit_ptr -> value_a
* exp_s(- GET_UNIT_BIAS(unit_ptr)*unit_ptr -> value_a);
break;
default:
rc = (FlintType) 1.0;
}
return rc;
}
/* Multiquadratic Radial Basis Derivation functionS
* depending on Aux: 0 derivated to T
* 1 derivated to s (BIAS)
* 2 derivated to T if value_a holds norm ^ 2;
* 3 derivated to s if value_a holds norm ^ 2;
* others: const 1;
*/
FlintType ACT_DERIV_RBF_Multiquadratic(struct Unit *unit_ptr)
{
register FlintType rc; /* return value */
register FlintType norm_2; /* norm ^ 2 */
register FlintType bias; /* s */
bias = (FlintType) GET_UNIT_BIAS(unit_ptr);
switch (unit_ptr -> Aux.int_no)
{
case 0:
case 1:
/* derivated to BIAS: */
/* derivated to norm_2: */
norm_2 = RbfUnitGetNormsqr(unit_ptr);
rc = (FlintType) 1.0/(2.0 * sqrt(bias + norm_2));
break;
case 2:
case 3:
/* derivated to BIAS: (norm ^ 2 = value_a) */
/* derivated to norm_2: (norm ^ 2 = value_a) */
rc = (FlintType) 1.0/(2.0 * sqrt(bias + unit_ptr -> value_a));
break;
default:
rc = (FlintType) 1.0;
}
return rc;
}
/* Thin Plate Spline Radial Basis Derivation functionS
* depending on Aux: 0 derivated to T
* 1 derivated to s (BIAS)
* 2 derivated to T if value_a holds norm ^ 2;
* 3 derivated to s if value_a holds norm ^ 2;
* others: const 1;
*/
FlintType ACT_DERIV_RBF_Thinplatespline(struct Unit *unit_ptr)
{
register FlintType rc; /* return value */
register FlintType norm_2; /* norm ^ 2 */
register FlintType bias; /* s */
bias = (FlintType) GET_UNIT_BIAS(unit_ptr);
switch (unit_ptr -> Aux.int_no)
{
case 0:
/* derivated to norm_2: */
norm_2 = RbfUnitGetNormsqr(unit_ptr);
if (norm_2 == (FlintType) 0.0)
rc = (FlintType) 0.0;
else
rc = (FlintType) bias * bias *
(log(norm_2) + 2.0*log(bias) + 1.0) / 2.0;
break;
case 1:
/* derivated to BIAS: */
norm_2 = RbfUnitGetNormsqr(unit_ptr);
if (norm_2 == (FlintType) 0.0)
rc = (FlintType) 0.0;
else
rc = (FlintType) bias * norm_2 *
(log(norm_2) + 2.0*log(bias) + 1.0);
break;
case 2:
/* derivated to norm_2: (norm ^ 2 = value_a) */
if (unit_ptr -> value_a == (FlintType) 0.0)
rc = (FlintType) 0.0;
else
rc = (FlintType) bias * bias *
(log(unit_ptr -> value_a) + 2.0*log(bias) + 1.0) / 2.0;
break;
case 3:
/* derivated to BIAS: (norm ^ 2 = value_a) */
if (unit_ptr -> value_a == (FlintType) 0.0)
rc = (FlintType) 0.0;
else
rc = (FlintType) bias * unit_ptr -> value_a *
(log(unit_ptr -> value_a) + 2.0*log(bias) + 1.0);
break;
default:
rc = (FlintType) 1.0;
}
return rc;
}
/*#################################################
GROUP: Site functions
#################################################*/
/* Linear Site Function
*/
FlintType SITE_WeightedSum(struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_SITE_LINK( site_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
return( sum );
}
/* Product of all predecessor outputs and input link weights
*/
FlintType SITE_Product(struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType prod;
if (GET_FIRST_SITE_LINK( site_ptr )) {
prod = 1.0;
do
prod *= GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
return( prod );
}
else
return( (FlintType) 0.0 );
}
/* Like SITE_Product() but no weighting of the unit's output
*/
FlintType SITE_ProductA(struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType prod;
if (GET_FIRST_SITE_LINK( site_ptr )) {
prod = 1.0;
do
prod *= GET_OUTPUT;
while (GET_NEXT_LINK);
/* Future Application (in SNNS-Kernel V2.1 the sites don't have weights).
So the return value is only the product.
*/
return( GET_SITE_WEIGHT * prod );
}
else
return( (FlintType) 0.0 );
}
/* Get the highest weighted output
*/
FlintType SITE_Max(struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType max, out;
if (GET_FIRST_SITE_LINK( site_ptr )) {
max = GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK) {
out = GET_WEIGHTED_OUTPUT;
if (max < out) max = out;
}
return( max );
}
else
return( (FlintType) 0.0 );
}
/* Get the lowest weighted output
*/
FlintType SITE_Min(struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType min, out;
if (GET_FIRST_SITE_LINK( site_ptr )) {
min = GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK) {
out = GET_WEIGHTED_OUTPUT;
if (min > out) min = out;
}
return( min );
}
else
return( (FlintType) 0.0 );
}
FlintType SITE_at_least_2 (struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType sum = 0.0;
sum = 0.0;
if (GET_FIRST_SITE_LINK (site_ptr))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
if (sum >= 2.0) {
return ( (FlintType) 1.0);
} else {
return ( (FlintType) 0.0);
} /*if*/
} /* SITE_at_least_2 */
FlintType SITE_at_least_1 (struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType sum = 0.0;
sum = 0.0;
if (GET_FIRST_SITE_LINK (site_ptr))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
if (sum >= 1.0) {
return ( (FlintType) 1.0);
} else {
return ( (FlintType) 0.0);
} /*if*/
} /* SITE_at_least_1 */
FlintType SITE_at_most_0 (struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType sum = 0.0;
sum = 0.0;
if (GET_FIRST_SITE_LINK (site_ptr))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
if (sum <= 0.0) {
return ( (FlintType) 1.0);
} else {
return ( (FlintType) 0.0);
} /*if*/
} /* SITE_at_most_0 */
/* IMPORTANT:
This function doesn't check for overflows. So make sure
that sum is greater than 0.0 when using this Site function.
*/
FlintType SITE_Reciprocal_WeightedSum (struct Site *site_ptr)
{
SITE_FUNC_DEFS
register FlintType sum = 0.0;
sum = 0.0;
if (GET_FIRST_SITE_LINK( site_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
if (sum == 0.0) {
return (0.0);
} else {
return((FlintType) (1/sum));
} /*if*/
} /* SITE_Reciprocal_WeightedSum */
FlintType ACT_LogisticSym(struct Unit *unit_ptr)
{
ACT_FUNC_DEFS
register FlintType sum;
sum = 0.0;
if (GET_FIRST_UNIT_LINK( unit_ptr ))
do
sum += GET_WEIGHTED_OUTPUT;
while (GET_NEXT_LINK);
else
if (GET_FIRST_SITE( unit_ptr ))
do
sum += GET_SITE_VALUE;
while (GET_NEXT_SITE);
return( (FlintType) (1.0 / (1.0 + exp_s( -sum - GET_UNIT_BIAS( unit_ptr ))))-0.5);
}
FlintType ACT_DERIV_LogisticSym(struct Unit *unit_ptr)
{
return( 0.25 - GET_UNIT_ACT( unit_ptr ) * GET_UNIT_ACT( unit_ptr ));
}
FlintType ACT_DERIV_tanh(struct Unit *unit_ptr)
{
return( 2 * (1.0 - GET_UNIT_ACT( unit_ptr )) * GET_UNIT_ACT( unit_ptr ));
}
FlintType ACT_RCC_Logistic(struct Unit *unit_ptr)
{
int reset;
struct Link *LinkPtr;
register FlintType sum;
reset = unit_ptr->lln;
sum = 0.0;
if(IS_HIDDEN_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return((FlintType)(1.0 / (1.0 + exp_s( -sum - unit_ptr->bias))));
}
else if(IS_SPECIAL_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return((FlintType)(1.0 / (1.0 + exp_s( -sum - unit_ptr->bias ))));
}
else if(IS_OUTPUT_UNIT(unit_ptr)){
FOR_ALL_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return( (FlintType) (1.0 / (1.0 + exp_s( -sum - unit_ptr->bias ))));
}
FlintType ACT_RCC_LogisticSym(struct Unit *unit_ptr)
{
int reset;
struct Link *LinkPtr;
register FlintType sum;
reset = unit_ptr->lln;
sum = 0.0;
if(IS_HIDDEN_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) (1.0 / (1.0 + exp_s( -sum - unit_ptr->bias))-0.5));
}
else if(IS_SPECIAL_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) (1.0 / (1.0 + exp_s( -sum - unit_ptr->bias))-0.5));
}
else if(IS_OUTPUT_UNIT(unit_ptr)){
FOR_ALL_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return( (FlintType) ((1.0 / (1.0 + exp_s( -sum - unit_ptr->bias)))-0.5));
}
FlintType ACT_RCC_Tanh(struct Unit *unit_ptr)
{
int reset;
struct Link *LinkPtr;
register FlintType sum;
reset = unit_ptr->lln;
sum = 0.0;
if(IS_HIDDEN_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) tanh(sum + unit_ptr->bias));
}
else if(IS_SPECIAL_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) tanh(sum + unit_ptr->bias));
}
else if(IS_OUTPUT_UNIT(unit_ptr)){
FOR_ALL_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) tanh(sum + unit_ptr->bias));
}
FlintType ACT_RCC_Linear(struct Unit *unit_ptr)
{
struct Link *LinkPtr;
register FlintType sum;
int reset;
reset = unit_ptr->lln;
sum = 0.0;
if(IS_HIDDEN_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) (sum + unit_ptr->bias));
}
else if(IS_SPECIAL_UNIT(unit_ptr)) {
if(!reset){
FOR_ALL_LINKS(unit_ptr,LinkPtr){
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
else {
FOR_ALL_NOT_RECURRENT_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) (sum + unit_ptr->bias));
}
else if(IS_OUTPUT_UNIT(unit_ptr)){
FOR_ALL_LINKS(unit_ptr,LinkPtr) {
sum += LinkPtr->weight * LinkPtr->to->Out.output;
}
}
return ((FlintType) (sum + unit_ptr->bias));
}
#ifdef __BORLANDC__
#pragma option -w+.
#endif